#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "sqlite3.h"  // 使用单文件 sqlite3.c
#include "miniz.h"    // 使用单文件 miniz.c

// 输出日志
void logMessage(const std::string& message) {
    std::cout << "[LOG] " << message << std::endl;
}

// 输出错误信息
void logError(const std::string& error) {
    std::cerr << "[ERROR] " << error << std::endl;
}

// 获取数据库中的所有表名
std::vector<std::string> getAllTables(sqlite3* db) {
    std::vector<std::string> tables;
    const char* sql = "SELECT name FROM sqlite_master WHERE type='table';";
    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        logError("查询表名失败: " + std::string(sqlite3_errmsg(db)));
        return tables;
    }

    while (sqlite3_step(stmt) == SQLITE_ROW) {
        const unsigned char* tableName = sqlite3_column_text(stmt, 0);
        tables.push_back(std::string(reinterpret_cast<const char*>(tableName)));
    }

    sqlite3_finalize(stmt);
    return tables;
}

// 导出SQLite数据库中的指定表到SQL文件
void exportTableToMySQL(sqlite3* db, const std::string& tableName, std::ofstream& outfile) {
    std::string sql = "SELECT * FROM " + tableName + ";";
    sqlite3_stmt* stmt;
    int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);

    if (rc != SQLITE_OK) {
        logError("查询执行失败: " + std::string(sqlite3_errmsg(db)));
        return;
    }

    // 查询表的列数
    int numColumns = sqlite3_column_count(stmt);
    outfile << "CREATE TABLE " << tableName << " (";
    for (int i = 0; i < numColumns; ++i) {
        if (i > 0) outfile << ", ";
        outfile << sqlite3_column_name(stmt, i) << " TEXT";  // 默认处理为TEXT类型
    }
    outfile << ");\n";

    while (sqlite3_step(stmt) == SQLITE_ROW) {
        outfile << "INSERT INTO " << tableName << " VALUES (";
        for (int i = 0; i < numColumns; ++i) {
            if (i > 0) outfile << ", ";
            if (sqlite3_column_type(stmt, i) == SQLITE_TEXT) {
                outfile << "'" << sqlite3_column_text(stmt, i) << "'";
            } else if (sqlite3_column_type(stmt, i) == SQLITE_INTEGER) {
                outfile << sqlite3_column_int(stmt, i);
            } else {
                outfile << "NULL";  // 处理 NULL 和其他类型
            }
        }
        outfile << ");\n";
    }

    sqlite3_finalize(stmt);
}

// 导出SQLite数据库到SQL文件的函数
void exportToMySQL(sqlite3* db, const std::string& outputFile) {
    logMessage("开始导出SQLite数据到SQL文件: " + outputFile);
    
    std::ofstream outfile(outputFile);
    if (!outfile) {
        logError("无法创建SQL文件: " + outputFile);
        return;
    }

    std::vector<std::string> tables = getAllTables(db);
    if (tables.empty()) {
        logError("数据库中没有表。");
        return;
    }

    for (const std::string& table : tables) {
        logMessage("正在导出表: " + table);
        exportTableToMySQL(db, table, outfile);
    }

    outfile.close();
    logMessage("数据导出成功到文件: " + outputFile);
}

// 创建压缩包的函数
void createZipFile(const std::string& sqlFile, const std::string& zipFile) {
    logMessage("开始创建ZIP文件: " + zipFile);

    // 创建 ZIP 压缩包
    mz_zip_archive zip_archive;
    memset(&zip_archive, 0, sizeof(zip_archive));

    // 开始创建ZIP
    if (!mz_zip_writer_init_file(&zip_archive, zipFile.c_str(), 0)) {
        logError("无法创建ZIP文件: " + zipFile);
        return;
    }

    // 将 SQL 文件添加到 ZIP
    if (!mz_zip_writer_add_file(&zip_archive, sqlFile.c_str(), sqlFile.c_str(), nullptr, 0, MZ_DEFAULT_COMPRESSION)) {
        logError("无法将SQL文件添加到ZIP: " + sqlFile);
        mz_zip_writer_end(&zip_archive);
        return;
    }

    // 完成 ZIP 文件
    mz_zip_writer_finalize_archive(&zip_archive);
    mz_zip_writer_end(&zip_archive);

    logMessage("ZIP文件创建成功: " + zipFile);

    // 删除临时SQL文件
    if (remove(sqlFile.c_str()) == 0) {
        logMessage("临时文件删除成功: " + sqlFile);
    } else {
        logError("删除临时文件失败: " + sqlFile);
    }
}

int main(int argc, char* argv[]) {
    std::string dbFile;
    std::string zipFile;
    std::string sqlFile = "database.sql";  // 临时SQL文件

    // 解析命令行参数
    int opt;
    while ((opt = getopt(argc, argv, "d:z:")) != -1) {
        switch (opt) {
            case 'd':
                dbFile = optarg;
                break;
            case 'z':
                zipFile = optarg;
                break;
            default:
                logError("用法: " + std::string(argv[0]) + " -d <dbfile> -z <zipfile>");
                return 1;
        }
    }

    if (dbFile.empty() || zipFile.empty()) {
        logError("必须同时指定数据库文件(-d)和输出的ZIP文件(-z)。");
        return 1;
    }

    logMessage("开始转换进程...");
    logMessage("SQLite 数据库文件: " + dbFile);
    logMessage("输出 ZIP 文件: " + zipFile);

    // 打开SQLite数据库
    sqlite3* db;
    int rc = sqlite3_open(dbFile.c_str(), &db);
    if (rc) {
        logError("无法打开SQLite数据库: " + std::string(sqlite3_errmsg(db)));
        return rc;
    }
    logMessage("成功打开SQLite数据库: " + dbFile);

    // 导出数据到SQL文件
    exportToMySQL(db, sqlFile);

    // 创建ZIP文件
    createZipFile(sqlFile, zipFile);

    // 关闭SQLite数据库
    sqlite3_close(db);
    logMessage("转换与压缩过程成功完成。");

    return 0;
}